03. Defining Java Modules

Defining Java Modules

ND079 JPND C3 L3 A03 Defining Java Modules V3

Module Keywords

The three main keywords for defining modules:

  • module: Declare a new class of the type module. Accepts a module name parameter with the same naming restrictions as packages. It is common to include the top level package as part of your module name, to ensure uniqueness.
  • exports: Identify a package that should be available to users of this module. Takes a package name as a parameter. Does not include subpackages.
  • requires: Make the packages in the specified module available in this module. Takes a module name as a parameter. You cannot require a package that also requires you. Circular dependencies will not compile.

Example:

module-info.java

module com.udacity.jpnd.module1 {
    exports com.udacity.jpnd.module1.somepackage;
    requires com.udacity.jpnd.module2;
}

Additional Keywords

ND079 JPND C3 L3 A04 Additional Java Module Keywords V3

Additional Module Keywords

  • **to: **The to keyword can be used to modify exports to limit which modules can access the specified package.
  • **transitive: **The transitive keyword modifies the requires keyword and specifies that the required module will also be made available to any other module that includes this module.
  • **opens: **Makes the specified package available for both public and private class reflection access. Can optionally use the to keyword to limit which modules have this access.
module com.udacity.jpnd.module1 {
    exports com.udacity.jpnd.publicpackage;
    exports com.udacity.jpnd.internalpackage to com.udacity.jpnd.module3;
    opens com.udacity.jpnd.internalpackage to com.udacity.jpnd.module3;
    requires transitive com.udacity.jpnd.module2;
}

Exports is used to provide compile-time access to packages, while opens is used to provide runtime access to packages.

Compile-time Access: Required for actions validated by the compiler, such as creating instances of classes and calling their methods.

Runtime Access: Required for actions not validated by the compiler, such as retrieving and executing the methods of a class via the Reflection API.

Access Provided By Commands

Access Provided By Commands

Service Provider Interface

Modules also interact with the Java Service Provider Interface (SPI), which is a way for Java to dynamically discover and load implementations for a specified interface. This was introduced in Java 6 and is not covered as a part of this lesson.

To declare or use a service defined by the SPI, you can use the provides/with and uses keywords.

module module1  {
    exports module1.somepackage;
    provides module1.somepackage.MyInterface with module1.somepackage.MyInterfaceImpl;
}

module module2 {
    requires module1;
    uses module1.somepackage.MyInterface;
}

For more information on Service Loaders, see:
https://docs.oracle.com/javase/9/docs/api/java/util/ServiceLoader.html